<template>
  <main-page title="表单设计器">
    <div class="form-designer">
      <div class="filter">
        <span class="filter-item">
          <span class="label">表单名称：</span>
          <el-input
            v-model="layoutName"
            size="small"
            style="width: 200px"
            @keyup.enter.native="searchClick"
          ></el-input>
        </span>
        <span class="filter-item">
          <span class="label">业务模块：</span>
          <el-cascader
            ref="cascader"
            v-model="classificationIds"
            class="classification-id"
            size="small"
            :options="options"
            :show-all-levels="false"
            :props="{ multiple: true, value: 'id', expandTrigger: 'hover' }"
            collapse-tags
            clearable
            style="width: 250px"
          ></el-cascader>
        </span>
        <el-button type="primary" @click="searchClick">查询</el-button>
        <el-button type="text" @click="resetClick">重置</el-button>
        <el-button
          v-permission="['systemConfig:formDesigner:add']"
          type="primary"
          style="margin-left: auto"
          @click="addClick"
        >
          新增
        </el-button>
      </div>
      <div class="content">
        <FormTable :table-data="tableData" :table-label="tableLabel">
          <template #operation="slotProps">
            <el-button
              v-permission="['systemConfig:formDesigner:edit']"
              type="text"
              class="operationBtn"
              @click="editClick(slotProps.row)"
            >
              编辑
            </el-button>
            <el-button
              v-permission="['systemConfig:formDesigner:designForm']"
              type="text"
              class="operationBtn"
              @click="designForm(slotProps.row)"
            >
              设计表单
            </el-button>
            <el-button
              v-permission="['systemConfig:formDesigner:searchConfig']"
              type="text"
              class="operationBtn"
              @click="searchFormSetting('init', slotProps.row)"
            >
              搜索配置
            </el-button>
            <el-tooltip
              v-permission="['systemConfig:formDesigner:del']"
              class="item"
              :disabled="!slotProps.row.isUsed"
              content="表单已被使用，不可删除!"
              placement="top"
            >
              <span>
                <el-popconfirm
                  confirm-button-text="删除"
                  cancel-button-text="取消"
                  icon="el-icon-info"
                  icon-color="red"
                  :title="`确定删除${slotProps.row.layoutName}吗？`"
                  @confirm="delForm(slotProps.row.layoutId)"
                >
                  <el-button slot="reference" type="text" :disabled="slotProps.row.isUsed" class="operationBtn">
                    删除
                  </el-button>
                </el-popconfirm>
              </span>
            </el-tooltip>
          </template>
        </FormTable>
      </div>
      <pagination
        style="height: 50px"
        :search-data="searchData"
        :table-total-size="tableTotalSize"
        @getTableData="getFormLayoutPageList"
      />
    </div>

    <el-dialog
      :visible.sync="dialogVisibel"
      width="480px"
      :title="dialogTitle"
      destory-on-close
      append-to-body
      @open="dialogOpen"
      @closed="dialogClose"
    >
      <div>
        <el-form
          v-if="dialogVisibel"
          ref="form"
          label-position="right"
          label-width="80px"
          size="small"
          :rules="rules"
          :model="formData"
        >
          <el-form-item label="表单名称" prop="layoutName">
            <el-input v-model.trim="formData.layoutName" maxlength="20" show-word-limit></el-input>
          </el-form-item>
          <el-form-item label="业务模块" prop="businessModule">
            <el-select
              v-model="formData.businessModule"
              placeholder="请选择"
              :disabled="dialogTitle === '修改表单'"
              @change="businessModuleChange"
            >
              <el-option
                v-for="item in businessModuleList"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="类别" prop="classificationId">
            <el-tooltip
              class="item"
              :disabled="(dialogTitle === '修改表单' && !row.isUsed) || dialogTitle === '新增表单'"
              content="表单已被使用，不可编辑!"
              placement="top"
            >
              <span>
                <el-tree-select
                  ref="treeSelect"
                  v-model="formData.classificationId"
                  :disabled="dialogTitle === '修改表单' && row.isUsed"
                  :select-params="selectParams"
                  :tree-params="treeParams"
                />
              </span>
            </el-tooltip>
          </el-form-item>
        </el-form>
        <div v-if="dialogTitle === '新增表单'" style="text-align: center">
          <el-checkbox v-model="openFormGenerator">添加后自动打开设计器</el-checkbox>
        </div>
      </div>
      <template #footer>
        <div style="text-align: center">
          <el-button @click="dialogVisibel = false">取消</el-button>
          <el-button type="primary" @click="submitForm">确认</el-button>
        </div>
      </template>
    </el-dialog>
    <FormGeneratorDrawer ref="FormGeneratorDrawer" @saveFormConfig="saveFormConfig" />
    <el-dialog :visible.sync="dialogSearchVisibel" width="500px" title="搜索配置" destory-on-close append-to-body>
      <div style="max-height: 450px; overflow-y: auto">
        <el-form ref="searchForm" label-position="right" label-width="110px" size="small" :model="searchForm">
          <el-form-item
            v-for="item in searchFormLabel"
            :key="item.componentId"
            :label="item.propertyName"
            :prop="item.componentId + ''"
          >
            <el-select
              v-model="searchForm[item.componentId + '']"
              placeholder="请选择"
              clearable
              @change="$forceUpdate()"
            >
              <el-option
                v-for="row in searchModeOptionList"
                :key="row.value"
                :label="row.label"
                :value="row.value"
              ></el-option>
            </el-select>
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <div style="text-align: center">
          <el-button @click="dialogSearchVisibel = false">取消</el-button>
          <el-button type="primary" :loading="search_loading" @click="searchFormSetting('save')">确认</el-button>
        </div>
      </template>
    </el-dialog>
  </main-page>
</template>

<script>
import MainPage from '@/components/main-page/index.vue'
import FormTable from '@/components/form-table/index.vue'
import pagination from '@/components/Table/pagination.vue'
import FormGeneratorDrawer from '@/components/form-generator/FormGeneratorDrawer.vue'
import {
  getFormLayoutPageList,
  addFormTemplate,
  getClassificationList,
  deleteFormTemplate,
  editFormTemplate,
  editFormLayout,
  getSearchModeOptionList,
  getFormComponentSearchConfigByLayoutId,
  addOrUpdateFormComponentSearchConfig
} from '@/api/system-config.js'
import defaultSettings from '@/settings'
import { generateUUID, postMessage, receivedMessage } from '@/utils/index'

export default {
  name: 'FormDesigner',
  components: { MainPage, FormTable, pagination, FormGeneratorDrawer },

  provide() {
    return {
      FromGeneratorBusinessModule: () => this.FromGeneratorBusinessModule
    }
  },
  data() {
    return {
      classificationIds: [],
      options: [],
      layoutName: '',
      businessModule: [],
      searchData: { currentPage: 1, pageSize: 10 },
      tableTotalSize: 0,
      dialogVisibel: false,
      formData: { layoutName: '', businessModule: 1, classificationId: '' },
      classificationList: [],
      tableData: [],
      dialogTitle: '',
      isLoading: false,
      openFormGenerator: true,
      FromGeneratorBusinessModule: '',
      selectParams: {
        multiple: false,
        clearable: true,
        placeholder: '请输入内容'
      },
      treeParams: {
        clickParent: false,
        filterable: false,
        'check-strictly': true,
        'default-expand-all': true,
        'expand-on-click-node': true,
        data: [],
        props: {
          children: 'children',
          label: 'label',
          disabled: 'disabled',
          value: 'id'
        }
      },
      businessModuleList: [
        {
          label: '被控芯片参数模块',
          value: 1
        }
      ],
      rules: {
        layoutName: [{ required: true, message: '请输入表单名称', trigger: 'blur' }],
        businessModule: [{ required: true, message: '请选择业务模块', trigger: 'blur' }],
        classificationId: [{ required: true, message: '请选择类别', trigger: 'blur' }]
      },
      tableLabel: [
        {
          prop: 'No',
          label: '序号',
          width: 60
        },
        {
          prop: 'layoutName',
          label: '表单名称'
        },
        {
          prop: 'businessModuleName',
          label: '业务模块'
        },
        {
          prop: 'classificationName',
          label: '类别'
        },
        {
          prop: 'createTime',
          label: '创建时间'
        },
        {
          prop: 'operation',
          label: '操作',
          type: 'slot'
        }
      ],
      // 搜索配置
      searchModeOptionList: [],
      searchFormLabel: [],
      dialogSearchVisibel: false,
      searchForm: {},
      search_loading: false,
      isOpenDesignForm: false,
      getFormLayoutPageListRequestId: generateUUID(),
      designFormData: {},
      addFormTemplateRequestId: generateUUID(),
      getAllClassificationListRequestId: generateUUID(),
      deleteFormTemplateRequestId: generateUUID(),
      editFormTemplateRequestId: generateUUID(),
      editFormLayoutRequestId: generateUUID(),
      getFormComponentSearchConfigByLayoutIdRequestId: generateUUID(),
      addOrUpdateFormComponentSearchConfigRequestId: generateUUID()
    }
  },
  created() {
    this.getFormLayoutPageList()
    // this.getSearchModeOptionList()
    this.getAllClassificationList()
  },
  mounted() {
    receivedMessage(this.dataHandle)
  },
  methods: {
    dataHandle(result) {
      let self = this
      let e = defaultSettings.isWPF ? result : { data: JSON.parse(result) }
      let res = e.data.response
      switch (e.data.webInfo.requestId) {
        case self.getFormLayoutPageListRequestId:
          self.tableData = res.data.map((item, index) => ({
            ...item,
            No: self.searchData.pageSize * (self.searchData.currentPage - 1) + index + 1
          }))
          self.tableTotalSize = res.total_count
          self.isLoading = false
          if (self.isOpenDesignForm) {
            self.isOpenDesignForm = false
            if (self.openFormGenerator) {
              console.log(self.designFormData)
              self.designForm(self.designFormData)
            }
          }
          break
        case self.addFormTemplateRequestId:
          if (res.success) {
            self.$message.success('表单增加成功！')
            self.dialogVisibel = false
            self.searchData.currentPage = 1
            self.isOpenDesignForm = true
            self.designFormData = e.data.response.data
            self.getFormLayoutPageList()
          } else {
            self.$message.error(res.message)
          }
          break
        case self.getAllClassificationListRequestId:
          self.setClassificationList(e.data.response)
          break
        case self.getClassificationListRequestId:
          self.$refs.treeSelect.treeDataUpdateFun(res.data)
          self.formData.classificationId = res.data[0]?.id
          if (self.dialogTitle === '修改表单') {
            self.formData.classificationId = self.row.classificationId
          }
          break
        case self.deleteFormTemplateRequestId:
          if (res.success) {
            self.$message.success('表单删除成功！')
            if (self.tableData.length <= 1) {
              self.searchData.currentPage = 1
            }
            self.getFormLayoutPageList()
          } else {
            self.$message.error(res.message)
          }
          break
        case self.editFormTemplateRequestId:
          if (res.success) {
            self.$message.success('表单修改成功！')
            self.dialogVisibel = false
            self.getFormLayoutPageList()
          } else {
            self.$message.error(res.message)
          }
          break
        case self.editFormLayoutRequestId:
          if (res.success) {
            self.$message.success('表单保存成功！')
            self.getFormLayoutPageList()
            self.$refs.FormGeneratorDrawer.saved()
          } else {
            self.$message.error(res.message)
          }
          break
        case self.getFormComponentSearchConfigByLayoutIdRequestId:
          self.searchFormLabel = res.data
          self.searchFormLabel.forEach((item) => {
            self.searchForm[item.componentId + ''] = item.searchMode ?? ''
          })
          self.dialogSearchVisibel = true
          break
        case self.addOrUpdateFormComponentSearchConfigRequestId:
          self.search_loading = false
          if (res.success) {
            self.$message.success('保存成功')
            self.dialogSearchVisibel = false
          } else {
            self.$message.error(res.message)
          }
          break
      }
    },
    getSearchModeOptionList() {
      getSearchModeOptionList().then((res) => {
        this.searchModeOptionList = res.data
      })
    },
    getAllClassificationList() {
      if (defaultSettings.isWPF || defaultSettings.isCEF) {
        this.getAllClassificationListRequestId = generateUUID()
        let message = {
          RequestUrl: process.env.VUE_APP_URL + '/formLayout/getClassificationList',
          RequestMethod: 'POST',
          Headers: {
            contentType: 'application/json'
          },
          QueryParameter: {},
          RequestBody: {
            businessModule: 1
          },
          WebInfo: {
            requestId: this.getAllClassificationListRequestId
          }
        }
        postMessage(message)
      } else {
        getClassificationList({ businessModule: 1 }).then((res) => {
          this.setClassificationList(res)
        })
      }
    },
    setClassificationList(res) {
      const delEmptyChildren = (arr) => {
        arr.forEach((item) => {
          if (item.children && item.children.length) {
            delEmptyChildren(item.children)
          } else {
            delete item.children
          }
        })
      }
      // 删除空的children[]
      delEmptyChildren(res.data)
      const businessModuleList = [
        {
          label: '被控芯片参数模块',
          id: 1,
          children: res.data
        }
      ]
      this.options = businessModuleList
    },
    searchFormSetting(type, row = {}) {
      if (type === 'init') {
        this.searchForm = {}
        if (defaultSettings.isWPF || defaultSettings.isCEF) {
          this.getFormComponentSearchConfigByLayoutIdRequestId = generateUUID()
          let message = {
            RequestUrl:
              process.env.VUE_APP_URL + '/formComponentSearchConfig/getFormComponentSearchConfigByLayoutId',
            RequestMethod: 'POST',
            Headers: {
              contentType: 'application/json'
            },
            QueryParameter: {},
            RequestBody: {
              layoutId: row.layoutId
            },
            WebInfo: {
              requestId: this.getFormComponentSearchConfigByLayoutIdRequestId
            }
          }
          postMessage(message)
        } else {
          getFormComponentSearchConfigByLayoutId({ layoutId: row.layoutId }).then((res) => {
            this.searchFormLabel = res.data
            this.searchFormLabel.forEach((item) => {
              this.searchForm[item.componentId + ''] = item.searchMode ?? ''
            })
            this.dialogSearchVisibel = true
          })
        }
      } else {
        this.searchFormLabel.forEach((item) => {
          item.searchMode = this.searchForm[item.componentId + '']
        })
        this.search_loading = true
        if (defaultSettings.isWPF || defaultSettings.isCEF) {
          this.addOrUpdateFormComponentSearchConfigRequestId = generateUUID()
          let message = {
            RequestUrl: process.env.VUE_APP_URL + '/formComponentSearchConfig/addOrUpdate',
            RequestMethod: 'POST',
            Headers: {
              contentType: 'application/json'
            },
            QueryParameter: {},
            RequestBody: this.searchFormLabel,
            WebInfo: {
              requestId: this.addOrUpdateFormComponentSearchConfigRequestId
            }
          }
          postMessage(message)
        } else {
          addOrUpdateFormComponentSearchConfig(this.searchFormLabel).then((res) => {
            this.search_loading = false
            if (res.success) {
              this.$message.success('保存成功')
              this.dialogSearchVisibel = false
            } else {
              this.$message.error(res.message)
            }
          })
        }
      }
    },
    getFormLayoutPageList() {
      this.isLoading = true
      const queryParams = [
        { businessModule: 1, classificationId: [] },
        { businessModule: 2, classificationId: [] }
      ]
      this.classificationIds?.forEach((item) =>
        queryParams[item[0] - 1].classificationId.push(item[item.length - 1])
      )
      queryParams[1].classificationId.length || queryParams.splice(1, 1)
      queryParams[0].classificationId.length || queryParams.splice(0, 1)
      if (defaultSettings.isWPF || defaultSettings.isCEF) {
        this.getFormLayoutPageListRequestId = generateUUID()
        let message = {
          RequestUrl: process.env.VUE_APP_URL + '/formLayout/getFormLayoutPageList',
          RequestMethod: 'POST',
          Headers: {
            contentType: 'application/json'
          },
          QueryParameter: {},
          RequestBody: {
            ...this.searchData,
            params: { layoutName: this.layoutName, queryParams }
          },
          WebInfo: {
            requestId: this.getFormLayoutPageListRequestId
          }
        }
        postMessage(message)
      } else {
        return getFormLayoutPageList({
          ...this.searchData,
          params: { layoutName: this.layoutName, queryParams }
        })
          .then((res) => {
            this.tableData = res.data.map((item, index) => ({
              ...item,
              No: this.searchData.pageSize * (this.searchData.currentPage - 1) + index + 1
            }))
            this.tableTotalSize = res.total_count
          })
          .finally(() => {
            this.isLoading = false
          })
      }
    },
    addClick() {
      this.dialogTitle = '新增表单'
      this.dialogVisibel = true
    },
    submitForm() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          if (this.dialogTitle === '新增表单') {
            const components = {
              fields: [],
              formRef: 'elForm',
              formModel: 'formData',
              size: 'medium',
              labelPosition: 'right',
              labelSuffix: '：',
              labelWidth: 100,
              formRules: 'rules',
              gutter: 15,
              disabled: false,
              span: 24,
              formBtns: false
            }
            if (defaultSettings.isWPF || defaultSettings.isCEF) {
              this.addFormTemplateRequestId = generateUUID()
              let message = {
                RequestUrl: process.env.VUE_APP_URL + '/formLayout/addFormTemplate',
                RequestMethod: 'POST',
                Headers: {
                  contentType: 'application/json'
                },
                QueryParameter: {},
                RequestBody: { ...this.formData, components },
                WebInfo: {
                  requestId: this.addFormTemplateRequestId
                }
              }
              postMessage(message)
            } else {
              addFormTemplate({ ...this.formData, components }).then((res) => {
                this.$message.success('表单增加成功！')
                this.dialogVisibel = false
                this.searchData.currentPage = 1
                this.getFormLayoutPageList().then(() => {
                  if (this.openFormGenerator) {
                    this.designForm(res.data)
                  }
                })
              })
            }
          } else {
            if (defaultSettings.isWPF || defaultSettings.isCEF) {
              this.editFormTemplateRequestId = generateUUID()
              let message = {
                RequestUrl: process.env.VUE_APP_URL + '/formLayout/editFormTemplate',
                RequestMethod: 'POST',
                Headers: {
                  contentType: 'application/json'
                },
                QueryParameter: {},
                RequestBody: { layoutId: this.editLayoutId, ...this.formData },
                WebInfo: {
                  requestId: this.editFormTemplateRequestId
                }
              }
              postMessage(message)
            } else {
              editFormTemplate({ layoutId: this.editLayoutId, ...this.formData }).then(() => {
                this.$message.success('表单修改成功！')
                this.dialogVisibel = false
                this.getFormLayoutPageList()
              })
            }
          }
        }
      })
    },
    saveFormConfig(data) {
      // return
      const options = []
      let isRequire = true
      const getOptions = (data) => {
        data.forEach(({ __config__ }) => {
          if (__config__.layout === 'rowFormItem') {
            getOptions(__config__.children)
          } else {
            const propertyDefinitionId = __config__.propertyDefinitionId
            if (propertyDefinitionId) {
              options.push({
                propertyDefinitionId: __config__.propertyDefinitionId
              })
            } else {
              isRequire = false
              this.$message.error('组件字段名为必选项，请重新检查！')
            }
          }
        })
      }
      getOptions(data.components.fields)
      if (!isRequire) {
        return
      }
      let params = {
        businessModule: this.row.businessModule,
        layoutId: data.layoutId,
        components: data.components,
        options
      }
      if (defaultSettings.isWPF || defaultSettings.isCEF) {
        this.editFormLayoutRequestId = generateUUID()
        let message = {
          RequestUrl: process.env.VUE_APP_URL + '/formLayout/editFormLayout',
          RequestMethod: 'POST',
          Headers: {
            contentType: 'application/json'
          },
          QueryParameter: {},
          RequestBody: params,
          WebInfo: {
            requestId: this.editFormLayoutRequestId
          }
        }
        postMessage(message)
      } else {
        editFormLayout(params).then(() => {
          this.$message.success('表单保存成功！')
          this.getFormLayoutPageList()
          this.$refs.FormGeneratorDrawer.saved()
        })
      }
    },
    businessModuleChange(val) {
      if (defaultSettings.isWPF || defaultSettings.isCEF) {
        this.getClassificationListRequestId = generateUUID()
        let message = {
          RequestUrl: process.env.VUE_APP_URL + '/formLayout/getClassificationList',
          RequestMethod: 'POST',
          Headers: {
            contentType: 'application/json'
          },
          QueryParameter: {},
          RequestBody: {
            businessModule: val
          },
          WebInfo: {
            requestId: this.getClassificationListRequestId
          }
        }
        postMessage(message)
      } else {
        return getClassificationList({ businessModule: val }).then((res) => {
          this.$refs.treeSelect.treeDataUpdateFun(res.data)
          this.formData.classificationId = res.data[0]?.id
        })
      }
    },
    resetClick() {
      this.layoutName = ''
      this.classificationIds = []
      this.getFormLayoutPageList()
    },
    searchClick() {
      this.searchData.currentPage = 1
      this.getFormLayoutPageList()
    },
    delForm(layoutId) {
      if (defaultSettings.isWPF || defaultSettings.isCEF) {
        this.deleteFormTemplateRequestId = generateUUID()
        let message = {
          RequestUrl: process.env.VUE_APP_URL + '/formLayout/deleteFormTemplate',
          RequestMethod: 'POST',
          Headers: {
            contentType: 'application/json'
          },
          QueryParameter: {},
          RequestBody: {
            layoutId
          },
          WebInfo: {
            requestId: this.deleteFormTemplateRequestId
          }
        }
        postMessage(message)
      } else {
        deleteFormTemplate({ layoutId }).then(() => {
          this.$message.success('表单删除成功！')
          if (this.tableData.length <= 1) {
            this.searchData.currentPage = 1
          }
          this.getFormLayoutPageList()
        })
      }
    },
    dialogOpen() {
      if (defaultSettings.isWPF || defaultSettings.isCEF) {
        this.businessModuleChange(this.formData.businessModule)
      } else {
        this.businessModuleChange(this.formData.businessModule).then(() => {
          if (this.dialogTitle === '修改表单') {
            this.formData.classificationId = this.row.classificationId
          }
        })
      }
    },
    dialogClose() {
      this.formData = { layoutName: '', businessModule: 1, classificationId: '' }
    },
    designForm(row) {
      if (row.isUsed) {
        this.$confirm('表单已被使用，请谨慎操作！', '提示', {
          confirmButtonText: '设计表单',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.row = row
          this.FromGeneratorBusinessModule = row.businessModule
          this.$refs.FormGeneratorDrawer.openDrawer(row)
        })
      } else {
        this.row = row
        this.FromGeneratorBusinessModule = row.businessModule
        this.$refs.FormGeneratorDrawer.openDrawer(row)
      }
    },
    editClick(row) {
      this.row = row
      this.formData.layoutName = row.layoutName
      this.formData.businessModule = row.businessModule
      this.editLayoutId = row.layoutId
      this.dialogTitle = '修改表单'
      this.dialogVisibel = true
    }
  }
}
</script>

<style lang="scss" scoped>
.filter {
  display: flex;
  padding-bottom: 20px;
  align-items: center;
  .filter-item {
    margin-right: 12px;
  }
}
.classification-id {
  height: 32px;
}
.operationBtn {
  padding: 10px 10px;
}
.el-form-item .el-tooltip .el-tree-select ::v-deep .el-select {
  width: 340px;
}
.el-select,
.el-input {
  width: 340px;
}
.form-designer {
  height: 100%;
  display: flex;
  flex-direction: column;
  .content {
    flex: 1;
    min-height: 200px;
  }
}
</style>
